package ma.mediascanner;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Timestamp;

import ma.beans.Media;
import ma.utils.HibernateUtils;

import org.hibernate.Session;
import java.util.*;

/**
 * Class: MediaScanner
 * @author Maik Lempik
 *
 */
public class MediaScanner {

String tvshows_path;
String movies_path;
Session session;
static final Properties properties = loadProperties();


/**
 * MediaScanner Default Constructor
 * @throws IOException 
 * @throws FileNotFoundException 
 */
public MediaScanner() throws FileNotFoundException, IOException {
	
	
		this.tvshows_path = properties.getProperty("tvshows_path");
		this.movies_path  = properties.getProperty("movies_path");
		
		this.session = HibernateUtils.getSessionFactory().getCurrentSession();
	
}

private static Properties loadProperties(){
	
	Properties properties = new Properties();
	try {
		properties.load(new FileInputStream("config.properties"));
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
	
	return properties;
	
}

/**
 * Method scan - Scans given directories (config.properties) for either movie or tv shows, parsing data into Vector of type Media
 * and provide it to MySQL database
 * @param type - 0 for TV show, 1 for Movies
 * @param userid
 * @throws Exception 
 * @throws IndexOutOfBoundsException 
 */
public void scan(int type, int userid) throws IndexOutOfBoundsException, Exception{
	switch (type) {
	case 0:
		scanDir(new File(this.tvshows_path), type, userid);
	break;
	case 1:
		scanDir(new File(this.movies_path), type, userid);
		break;
	default:
		break;
	}
	
}


private void scanDir(File dir, int type, int userid) throws IndexOutOfBoundsException, Exception {
	
	File[] files = dir.listFiles();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {

				if (files[i].isFile())
				{	
					saveMediaData(parseMetaDatafromAbsolutePath(files[i].getAbsolutePath(), type, userid));
					
				}
				else 
				{
					scanDir(files[i], type, userid); // calls itself with the sub directory as parameter, recursive loop
				}
			}
		}
	}	

/**
 * Method parseMetaDatafromAbsolutePath
 * @param path
 * @param type
 * @param userid
 * @return Media object
 * @throws IndexOutOfBoundsException
 */
private Media parseMetaDatafromAbsolutePath(String path, int type, int userid) throws IndexOutOfBoundsException{
		
		Media m = new Media();
		
		String fileext	= "void";
		String filename = "void";
		String title = "unknown";
		String genre = "unused";
		int season  = 0;
		int episode = 0;	
		
		if (path.charAt(path.length() - 4) == '.') {
			
			 filename = path.substring(path.lastIndexOf(File.separator)+1).trim();
			 fileext = path.substring(path.length() - 3);
			
			 
		 switch (type) {
			case 1:
				// title parser for movies in separate folders ( {Movie_Dir}/{Movie_name}/{Movie_name.ext} )
				 int beginIndex = path.substring(0,path.lastIndexOf(File.separator)).lastIndexOf(File.separator);
				 title = path.substring(beginIndex+1, path.lastIndexOf(File.separator));
				break;
			case 0:
				 // title parser for tv shows by folder pattern
				 String[] stitle = path.split(tvshows_path+File.separator);
				 title = stitle[1].substring(0, stitle[1].indexOf(File.separator));
				 
				 // Season/Episode Parser 1: trying the SxxExx (e.g. S01E01 - ...) filename pattern for season and episode 
				 if(filename.charAt(0) == 'S' && filename.charAt(3) == 'E'){
					 season = Integer.parseInt(filename.substring(1,3));
					 episode = Integer.parseInt(filename.substring(4, 6));
				 }
				 
				// Season/Episode Parser 2: Parsing Season from folder and episode from filename
				//
				// - not yet implemented - 
			default:
				break;
			}
		}
	
		//build media object
		if(!filename.equals("void")){
			m.setFilename(filename);
			m.setFormat(fileext);
			m.setTitle(title);
			
			if(type == 0){
				m.setMediatype("tvshow");
				m.setEpisode(episode);
				m.setSeason(season);
				m.setGenre(genre); // <- ?
			}else{
				m.setMediatype("movie");
				m.setGenre(genre); // <- ?
			}
						
			m.setScandate(new Timestamp(System.currentTimeMillis()).toString());	
			m.setOwnerid(userid);
			
			return m;
		
		}
		else { return null; }	
	}

public void saveMediaData(Media m) throws Exception{
	if(m!=null){
		if(this.session != null){
			this.session.beginTransaction();
			this.session.save(m);
//			this.session.getTransaction().commit();
		}else{
			throw new Exception("Hibernate Session is null.");
		}
	}
}

}
